package com.ruoqing.admin.api.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoqing.admin.api.UserHandleService;
import com.ruoqing.admin.api.UserStandardService;
import com.ruoqing.admin.dao.UserHandleDao;
import com.ruoqing.admin.feign.MailMessageServiceFeign;
import com.ruoqing.admin.feign.UserServiceFeign;
import com.ruoqing.core.constant.Constants;
import com.ruoqing.core.domain.rqadmin.BanUserPo;
import com.ruoqing.core.domain.rquser.UserEntity;
import com.ruoqing.core.dto.BaseResponse;
import com.ruoqing.core.dto.admin.AdminMessageDto;
import com.ruoqing.core.dto.admin.BanUserDto;
import com.ruoqing.core.dto.admin.BanUserPageDto;
import com.ruoqing.core.dto.user.UserPageDto;
import com.ruoqing.core.dto.user.UserResponse;
import com.ruoqing.core.enums.AdminMessageEnum;
import com.ruoqing.core.enums.RedisEntityEnum;
import com.ruoqing.core.enums.UserQueryEnum;
import com.ruoqing.core.fallback.callback.MySendCallback;
import com.ruoqing.utils.common.BeanSetterUtils;
import com.ruoqing.utils.common.DateUtils;
import com.ruoqing.utils.common.ObjectUtils;
import com.ruoqing.utils.common.RedisUtils;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
	* @author YaoXian
	* @title: UserHandleServiceImpl
	* @projectName ruoxi-blog
	* @description: 若兮微服务 - 后台管理中心 - 用户操作类业务层实现类
	* @date 2020-11-15 15:29
	*/
@Service
@Slf4j
public class UserHandleServiceImpl implements UserHandleService {
		
		@Resource
		private UserServiceFeign userServiceFeign;
		
		@Resource
		private MailMessageServiceFeign mailMessageServiceFeign;
		
		@Resource
		private UserStandardService userStandardService;
		
		@Resource
		private UserHandleDao userHandleDao;
		
		@Resource
		private RocketMQTemplate rocketMqTemplate;
		
		@Resource
		private RedisTemplate<String,BanUserPageDto> redisTemplate;
		
		public static List<String> redisKeys = new LinkedList<String>();
		
		@Override
		public String updateUser(UserEntity userEntity, String modifyReason) {
				UserResponse userResponse = userServiceFeign.updateUser(userEntity);
				userResponse.setUserEntity(userEntity);
				rocketMqTemplate.asyncSend("admin_topic:updateUser",AdminMessageDto.buildAdminMessageDto(AdminMessageEnum.updateUser,userResponse,modifyReason),new MySendCallback());
				return userResponse.getStatus();
		}
		
		@Override
		@GlobalTransactional(rollbackFor = Exception.class,name = "ruoqing-admin-deleteUser")
		public UserResponse deleteUser(int userId) {
				UserResponse userResponse = userServiceFeign.deleteUserById(userId);
				rocketMqTemplate.asyncSend("admin_topic:deleteUser",AdminMessageDto.buildAdminMessageDto(AdminMessageEnum.deleteUser,userResponse),new MySendCallback());
				userStandardService.addBlackUser(userResponse.getUserEntity().getPhoneNumber(),false);
				return userResponse;
		}
		
		@Override
		public UserResponse blurSelectUserByUserName(String queryParam, int condition) {
				String result;
				List<UserEntity> userEntityList = userServiceFeign.blurSelectUsers(queryParam,condition);
				if (!userEntityList.isEmpty()){
						result = Constants.responseOk;
				}else {
						result = Constants.responseError;
				}
				return UserResponse.buildUserResponse(result, userEntityList);
		}
		
		@Override
		public BanUserPageDto findBanUserByPage(Integer currentPage, Integer pageSize) {
				BanUserPageDto banUserPageDtoList = redisTemplate.boundValueOps(currentPage + RedisEntityEnum.redis_banUser.toString()).get();
				if (StringUtils.isEmpty(banUserPageDtoList)){
						QueryWrapper<BanUserPo> queryWrapper = new QueryWrapper<BanUserPo>();
						Page<BanUserPo> listPage = userHandleDao.selectPage(new Page<BanUserPo>(currentPage, pageSize), queryWrapper);
						ArrayList<BanUserDto> userDtoList = new ArrayList<BanUserDto>(pageSize);
						if (!listPage.getRecords().isEmpty()){
								for (BanUserPo banUser : listPage.getRecords()) {
										BanUserDto banUserDto = new BanUserDto();
										BeanUtils.copyProperties(banUser,banUserDto);
										banUserDto.setBanDateFormat(DateUtils.dateTimeToStr(banUser.getBanTime()));
										userDtoList.add(banUserDto);
								}
								BanUserPageDto banUserPageDto = new BanUserPageDto();
								BeanSetterUtils.setPageAttributes(banUserPageDto,listPage);
								banUserPageDto.setList(userDtoList);
								redisTemplate.boundValueOps(currentPage+ RedisEntityEnum.redis_banUser.toString()).set(banUserPageDto,30, TimeUnit.MINUTES);
								redisKeys.add(currentPage+ RedisEntityEnum.redis_banUser.toString());
								banUserPageDtoList = banUserPageDto;
								log.info("从MySQL数据库中取");
						}else {
								log.error("错误查询结果!");
						}
				}else {
						log.info("从Redis缓存中取");
						RedisUtils.closeRedisConnection(redisTemplate);
				}
				return banUserPageDtoList;
		}
		
		@Override
		public UserPageDto selectUserByPage(int currentPage, int pageSize) {
				Page<UserEntity> page = userServiceFeign.selectUserByPagination(currentPage, pageSize);
				UserPageDto userPageDto = new UserPageDto();
				BeanSetterUtils.setPageAttributes(userPageDto,page);
				userPageDto.setPageList(page.getRecords());
				return userPageDto;
		}
		
		@Override
		public UserResponse findUserByCondition(String queryParam, UserQueryEnum userQueryEnum) {
				UserEntity userEntity = userServiceFeign.findUserByCondition(queryParam,userQueryEnum);
				String status;
				if (ObjectUtils.isNull(userEntity)){
						status = Constants.responseError;
				}else {
						status = Constants.responseOk;
				}
				return UserResponse.buildUserResponse(status,userEntity);
		}
		
		@Override
		public BaseResponse insertUser(UserEntity userEntity) {
				BaseResponse baseResponse = userServiceFeign.addUser(userEntity);
				rocketMqTemplate.asyncSend("admin_topic:insertUser",
								AdminMessageDto.buildAdminMessageDto(AdminMessageEnum.insertUser,
												UserResponse.buildUserResponse(baseResponse.getStatus(),
																userEntity)),new MySendCallback());
				return baseResponse;
		}
		
		@Override
		public void removeRedisBanUser(List<String> redisKeys) {
				redisTemplate.delete(redisKeys);
				while (redisKeys.size() > 0){
						redisKeys.remove(0);
				}
		}
		
}
